home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 22 / Cream of the Crop 22.iso / program / cgazv4n3.zip / DROPMENU.CPP < prev    next >
C/C++ Source or Header  |  1990-02-05  |  3KB  |  91 lines

  1. // DROPMENU.CPP : methods for drop-menus
  2. // by Bruce Eckel. (c) The C Gazette
  3.  
  4. #include <string.h>
  5. #include <conio.h>
  6. #include "dropmenu.hpp"
  7. #include "scrnbox.hpp"
  8.  
  9. // The activation letter is preceded by a '^' :
  10. void dm_item::find_activation_letter() {
  11.   char * al = strchr(name, '^');
  12.   if(al)  // strchr returns NULL if not found
  13.     if(*++al)  // must not be end of string
  14.       activation_letter = *al;
  15. }
  16.  
  17. dm_item::dm_item(char * nm, int (*fp)(void)) :
  18.   name(nm), fptr(fp), mptr(NULL) {
  19.   find_activation_letter();
  20. }
  21.  
  22. dm_item::dm_item(char * nm, drop_menu * submenu) :
  23.   name(nm), mptr(submenu), fptr(NULL) {
  24.   find_activation_letter();
  25. }
  26.  
  27. // Print an individual item, emphasizing the activation letter:
  28. void dm_item::print(int line, screen_box & box) {
  29.   actual_line = line;
  30.   box.move(actual_line);
  31.   char * cp = name;
  32.   while(*cp) {
  33.     if(*cp == '^') { // next char in standout mode
  34.       if(*++cp)
  35.         box.emphasize(*cp++);
  36.     } else
  37.       box.put_c(*cp++);
  38.   }
  39. }
  40.  
  41. // Check to see if the keypress is this dm_item's activation letter.
  42. // If so, call the function or activate the submenu.
  43. void dm_item::test_and_execute(unsigned keypress, drop_menu & menu) {
  44.   if(keypress == activation_letter)
  45.     if(fptr != NULL) // means it's a function
  46.       (*fptr)();
  47.     else
  48.       mptr->activate(menu.y() + actual_line, menu.x() + menu.width());
  49. }
  50.  
  51. drop_menu::drop_menu(dm_item ** dm, unsigned xpos, unsigned ypos)
  52.   : items(dm) {
  53.   default_x = actual_x = xpos;
  54.   default_y = actual_y = ypos;
  55.   mheight = mwidth = 0;
  56.   // Determine the width and height of the menu:
  57.   while(*(items[mheight]->nm())) {
  58.     unsigned width = strlen(items[mheight]->nm());
  59.     // Check for a hotkey, which adds an unprinted char to the string:
  60.     if(strchr(items[mheight]->nm(), '^'))
  61.       width--;
  62.     if (width > mwidth) mwidth = width;
  63.     mheight++;
  64.   }
  65. }
  66.  
  67. // Bring up the menu in its default location if no arguments are
  68. // given, or the location specified by the arguments.  Note that
  69. // "location" is given in terms of text-mode x-y coords, even though
  70. // graphics mode may in fact be used.
  71. void drop_menu::activate(unsigned y, unsigned x) {
  72.   if (x == 0 && y == 0) {
  73.     actual_x = default_x;
  74.     actual_y = default_y;
  75.   } else {
  76.     actual_x = x;
  77.     actual_y = y;
  78.   }
  79.   // Create a menubox and print all the items to it:
  80.   screen_box menubox(actual_y, actual_x, mheight, mwidth);
  81.   for(int i = 0; i < mheight; i++) {
  82.     items[i]->print(i, menubox);
  83.   }
  84.   // get input and do the user's command:
  85.   test_keypress(getch());
  86. }
  87.  
  88. void drop_menu::test_keypress(unsigned keypress) {
  89.   for(int i = 0; i < mheight; i++)
  90.     items[i]->test_and_execute(keypress, *this);
  91. }